package org.classdef.analyzer.info.methodtype;

/**
 * 
 * class格式规范中的方法类型
 *
 */
public enum MethodType {
	
	BYTE("B", "BaseType", "byte"),
	CHAR("C", "BaseType", "char"),
	DOUBLE("D", "BaseType", "double"),
	FLOAT("F", "BaseType", "float"),
	INT("I", "BaseType", "int"),
	LONG("J", "BaseType", "long"),
	REFERENCE("L", "ObjectType", "reference"),
	SHORT("S", "BaseType", "short"),
	BOOLEAN("Z", "BaseType", "boolean"),
	VOID("V", "BaseType", "void"),
	ARRAY("[", "ArrayType", "reference");
	
	private String value;
	private String type;
	private String name;
	
	private MethodType(String value, String type, String name){
		this.value = value;
		this.type = type;
		this.name = name;
	}
	
	public String getValue() {
		return value;
	}

	public String getType() {
		return type;
	}

	public String getName() {
		return name;
	}
	
	private static MethodType getSingleType(String value){
		MethodType[] types = values();
		for (MethodType type : types) {
			if(type.getValue().equals(value)){
				return type;
			}
		}
		return null;
	}

	public static String getType(String value){
		if(value.startsWith("(")){
			int index = value.indexOf(")");
			String paramStr = value.substring(1, index);
			String params = paramStr.equals("") ? "" : getType(paramStr);
			String rtn = getType(value.substring(index + 1));
			
			return "(" + params + ")" + rtn;
			
		}else if(value.equals(VOID.getValue())){
			return VOID.getName();
		}
		
		return getRealType(value);
	}

	private static String getRealType(String value) {
		String v = String.valueOf(value.charAt(0));
		
		MethodType type = getSingleType(v);
		if(type.getType().equals("BaseType")){
			return getBaseType(value, type);
			
		}else if(type.getType().equals("ObjectType")){
			return getObjectType(value);
			
		}else if(type.getType().equals("ArrayType")){
			return getArrayType(value);
		}
		
		return "";
	}

	private static String getArrayType(String value) {
		int i = 1;
		while(value.charAt(i) == '['){
			i++;
		}
		String preName = "";
		MethodType arrType = getSingleType(String.valueOf(value.charAt(i)));
		if(arrType.getType().equals("BaseType")){
			preName = arrType.getName();
		}else if(arrType.getType().equals("ObjectType")){
			i = value.indexOf(";");
//						String preName = value.substring(1, endIndex).replaceAll("/", ".");
			String[] strs = value.substring(1, i).split("/");
			preName = strs[strs.length - 1];
		}
		
		String arrStr = "";
		for (int j = 0; j < i; j++) {
			arrStr += "[]";
		}
		
		if(value.length() > i + 1){
			return preName + arrStr + ", " + getType(value.substring(i + 1));
		}else {
			return preName + arrStr;
		}
	}

	private static String getObjectType(String value) {
		int endIndex = value.indexOf(";");
//					String typeName = value.substring(1, endIndex).replaceAll("/", ".");
		String[] strs = value.substring(1, endIndex).split("/");
		String typeName = strs[strs.length - 1];
		
		if(value.length() > endIndex + 1){
			return typeName + ", " + getType(value.substring(endIndex + 1));
		}else {
			return typeName;
		}
	}

	private static String getBaseType(String value, MethodType type) {
		if(value.length() > 1){
			return type.getName() + ", " + getType(value.substring(1));
		}else {
			return type.getName();
		}
	}

}
